using UnityEngine;
using System.Collections;

/// \class  gkAbyssalGiantFishEatAnimationController
/// \brief  Control the eat animation
[AddComponentMenu("GK/AbyssalGiant/GantFish/gkAbyssalGiantFishEatAnimationController")]
public class gkAbyssalGiantFishEatAnimationController : MonoBehaviour
{
	/// The distance of the target at which the owner begin to open is mouth
	public float OpenMouthBeginDistance = 20.0f;
	
	/// The distance of the target at which the owner can eat the target
	public float OpenMouthEndDistance = 5.0f;
	
	/// The anim time at which the mouth is totaly open
	public float MouthTotalyOpenTime = 0.4849f;
	
	/// Mouth opening blend time
	public float MouthOpeningBlendTime = 0.25f;
	
	/// Root of the bones tree that are influenced by the eat animation
	public Transform[] EatAnimationInfluencedBoneTreeRoots;
	
	/// The target
	public Transform Target;
	
	/// The Mouth
	public Transform Mouth;
	
	/// The distance from mouth to target
	private float m_fMouthToTargetDistance;
	
	/// The eat animation state
	private AnimationState m_rEatAnimationState;
	
	/// The idle mouth animation state
	private AnimationState m_rIdleMouthAnimationState;
	
	/// The idle animation state
	private AnimationState m_rIdleAnimationState;
	
	/// \brief  Called just after the game begin to play
	void Start()
	{	
		// Setup the eat animation
		SetupEatAnimation();
	}
	
	/// \brief  Called each frame
	void Update()
	{
		if(Target != null)
		{
			//Compute informations on the target proximity
			ComputeTargetProximityInfos();
		}
		
		// Update the mouth opening based on the target proximity
		UpdateMouthOpening();
		
		// Sync the idle animations
		SyncIdleAnimations();
	}
	
	/// \brief  Setup the eat animation
	void SetupEatAnimation()
	{
		// Grab the eat animation state
		m_rEatAnimationState = animation["GiantFish_Eat"];
		
		// Grab the idle animation state
		m_rIdleMouthAnimationState = animation["GiantFish_IdleMouth"];
		m_rIdleAnimationState = animation["GiantFish_Idle"];
		
		// Place the mouth animation on the layer 1
		m_rEatAnimationState.layer = 1;
		
		// The mouth animation rate is totally controlled by script
		m_rEatAnimationState.speed = 0.0f;
		m_rIdleMouthAnimationState.speed = 0.0f;
		
		// Loop through the Mouth bones to Add it to the roots mix transform
		// used for the eat animation
		foreach(Transform rTransform in EatAnimationInfluencedBoneTreeRoots)
		{
			m_rEatAnimationState.AddMixingTransform(rTransform, true);
			m_rIdleMouthAnimationState.AddMixingTransform(rTransform, true);
		}
		
	}
	
	/// \brief  Compute informations on the target proximity
	void ComputeTargetProximityInfos()
	{
		Vector3 f3MouthToTarget;
	
		// Compute the vector mouth to target
		f3MouthToTarget = Target.position - Mouth.position;
		f3MouthToTarget.z = 0.0f;
	
		// Compute the distance between the mouth and the target
		m_fMouthToTargetDistance = f3MouthToTarget.magnitude;
	}
	
	/// \brief  Update the mouth openning based on the target proximity
	void UpdateMouthOpening()
	{
		float fMouthOpeningPercentage;
	
		if(Target != null)
		{
			// If the owner is near enough of the target to open his mouth but not close enough to eat it
			if((m_fMouthToTargetDistance < OpenMouthBeginDistance))
			{
				if((m_fMouthToTargetDistance > OpenMouthEndDistance))
				{
					// Compute the mouth opening percentage
					fMouthOpeningPercentage = 
						(m_fMouthToTargetDistance - OpenMouthBeginDistance)/(OpenMouthEndDistance - OpenMouthBeginDistance);
				}
				else
				{
					fMouthOpeningPercentage = 1.0f;
				}
			}
			else
			{
				fMouthOpeningPercentage = 0.0f;
			}
			OpenMouth(fMouthOpeningPercentage, MouthOpeningBlendTime);
		}
		else
		{
			CloseMouth();
		}
	}

	/// \brief Open the mouth of a specific amount
	void OpenMouth(float a_fMouthOpeningPercentage, float a_fBlendTime)
	{
		m_rEatAnimationState.time = MouthTotalyOpenTime * a_fMouthOpeningPercentage;
		
		animation.Blend(m_rEatAnimationState.name, a_fMouthOpeningPercentage, a_fBlendTime);
		animation.Blend(m_rIdleMouthAnimationState.name, 1.0f - a_fMouthOpeningPercentage, a_fBlendTime);
	}
	
	/// \brief Open the mouth of a specific amount
	void CloseMouth()
	{
		animation.Blend(m_rEatAnimationState.name, 0.0f, m_rEatAnimationState.time);
		m_rEatAnimationState.speed = -1.0f;
	}
	
	/// \brief Open the mouth of a specific amount
	void SyncIdleAnimations()
	{
		m_rIdleMouthAnimationState.time = m_rIdleAnimationState.time;
	}
}